/*
 * WordSense
 * Copyright (C) 2008  Young,Fey <fey.young@gmail.com>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.youngfey.wordmaster.wordnet

import edu.smu.tspell.wordnet.SynsetType

class WordSense {

    private static final cache = [:]
    
    final String lemma
    final synsets = []
    final antonyms = [:]
    final derivatives = [:]

    /**
     *
     */
    static List<WordSense> lookup(String form) {
        cache.containsKey(form) ? cache[form] : lookupDictionary(form)
    }

    private static final lookupDictionary(form) {
        final senseMap = [:]
        final baseForms = getBaseForms(form)
        Synset.lookup(form).each { synset ->
            synset.getForms().each { f ->
                baseForms.each { b ->
                    if (b.equalsIgnoreCase(f)) {
                        if (senseMap.containsKey(f)) {
                            senseMap[f].addSynset(synset)
                        } else {
                            senseMap[f] = new WordSense(f, synset)
                        }
                    }                    
                }
            }
        }       
        def senses = senseMap.values().toList()
        cache[form] = senses
        senses.each { sense ->
            final String lemma = sense.getLemma();
            if (lemma != form && !cache.containsKey(lemma)) cache[lemma] = senses
        }
        senses
    }

    private WordSense(lemma, synset) {
        this.lemma = lemma
        addSynset(synset)
    }
    
    private final addSynset(synset) {
        if (!synsets.contains(synset)) {
            synsets << synset
            antonyms[synset] = synset.getAntonymMap().get(lemma)
            derivatives[synset] = synset.getDerivativeMap().get(lemma)
        }        
    }

    def print() {
        println "--- WordSense ----\nLemma: $lemma"
        synsets.each { s ->
            s.print()
            if(antonyms[s]) println "\tAntonyms: ${antonyms[s].join('\t')}"
            if(derivatives[s]) println "\tDerivatives: ${derivatives[s].join('\t')}"
        }        
    }

    private static final getBaseForms(inflection) {
        final forms = [inflection]
        SynsetType.ALL_TYPES.each { type ->
            WordNetDictionary.getDatabase().getBaseFormCandidates(inflection, type).each {
                if(!forms.contains(it)) forms << it
            }
        }
        forms
    }
}